package context

import (
	"net/http"
	"strings"
)

type Request struct {
	Context     *Context
	httpRequest *http.Request
	Info        RequestInfo
	params      Params
}

type RequestInfo struct {
	ChainID     string `json:"chainID"`
	AppKey      string `json:"appKey"`
	Action      string `json:"action"`
	ReferAction string `json:"referAction"`
	SessionKey  string `xorm:"-" json:"sessionKey"`
}

//设置RequestInfo对象值
func (r *RequestInfo) Set(key string, value string) bool {
	isFound := false
	key = strings.ToLower(key)

	switch key {
	case "chainid":
		isFound = true
		r.ChainID = value
	case "appkey":
		isFound = true
		r.AppKey = value
	case "action":
		isFound = true
		r.Action = value
	case "referaction":
		isFound = true
		r.ReferAction = value
	case "sessionkey":
		isFound = true
		r.SessionKey = value
	}

	return isFound
}

func (r *RequestInfo) NewRequestInfo(action string) map[string]string {
	m := make(map[string]string)
	m["chainID"] = r.ChainID
	m["appKey"] = r.AppKey
	m["action"] = action
	m["referAction"] = r.Action
	m["sessionKey"] = r.SessionKey

	return m
}

// 创建新的请求对象
func NewRequest() *Request {
	return &Request{}
}

// 重置Http请求对象
func (r *Request) Reset(ctx *Context, httpReq *http.Request) {
	r.Context = ctx
	r.httpRequest = httpReq

	// 整个URL地址
	//httpReq.URL.String()
	// URL路径
	//httpReq.URL.RawPath

	// GET 地址栏参数
	//	queryForm, err := url.ParseQuery(httpReq.URL.RawQuery)
	//	if err == nil && len(queryForm["id"]) > 0 {
	//		fmt.Fprintln(w, queryForm["id"][0])
	//	}

	// POST
	//httpReq.PostForm

	if httpReq.Form == nil {
		httpReq.ParseForm()
	}

	r.Info = RequestInfo{}
	r.params = make(Params, 0, len(httpReq.Form))
	for k, v := range httpReq.Form {
		isFound := r.Info.Set(k, v[0])
		if !isFound {
			r.params = append(r.params, param{strings.ToLower(k), v[0]})
		}
	}
}

// 微服务请求链条ID
func (r *Request) ChainID() string {
	return r.Info.ChainID
}

func (r *Request) AppKey() string {
	return r.Info.AppKey
}

func (r *Request) Action() string {
	return r.Info.Action
}

func (r *Request) SessionKey() string {
	return r.Info.SessionKey
}

// 引用参数对象
func (r *Request) Params() *Params {
	return &r.params
}

// 请求方法，GET或POST
func (r *Request) Method() string {
	return r.httpRequest.Method
}

// 获取原生http.Request对象
func (r *Request) HttpRequest() *http.Request {
	return r.httpRequest
}

// Header returns request header item string by a given string.
// if non-existed, return empty string.
func (r *Request) Header(key string) string {
	return r.httpRequest.Header.Get(key)
}

// Proxy returns proxy client ips slice.
func (r *Request) Proxy() []string {
	if ips := r.Header("X-Forwarded-For"); ips != "" {
		return strings.Split(ips, ",")
	}
	return []string{}
}

// IP returns request client ip.
// if in proxy, return first proxy id.
// if error, return 127.0.0.1.
func (r *Request) IP() string {
	ips := r.Proxy()
	if len(ips) > 0 && ips[0] != "" {
		rip := strings.Split(ips[0], ":")
		return rip[0]
	}
	ip := strings.Split(r.httpRequest.RemoteAddr, ":")
	if len(ip) > 0 {
		if ip[0] != "[" {
			return ip[0]
		}
	}
	return "127.0.0.1"
}
